package jp.androidgroup.chiba.androidresearch.oauth;

import jp.androidgroup.chiba.androidresearch.Constants;
import jp.androidgroup.chiba.androidresearch.UserInfo;
import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

/**
 * <pre>
 * SharedPreferencesに認証情報やユーザ情報を保存したり、
 * 保存された情報を取得するなど、SharedPreferences関連の処理を
 * 一手に引き受けるクラスです。
 * </pre>
 */
public class SharedPreferencesManager {

	private Context _context;

	/**
	 * コンストラクタ
	 *
	 * @param context
	 *            Context
	 */
	public SharedPreferencesManager(Context context) {
		_context = context;
	}

	/**
	 * SharedPreferencesに保存されているユーザ情報を取得します。<br>
	 * SharedPreferencesに保存されていない場合、UserInfoオブジェクト内の各データは空となります。
	 * ※最新のユーザ情報を取得しているわけではありません。<br>
	 *
	 * @return UserInfo
	 */
	public UserInfo getUserInfo() {
		return new UserInfo(getSharedPreferences());
	}

	/**
	 * UserInfo（ユーザ情報）をSharedPreferencesに保存します。
	 *
	 * @param userInfo
	 */
	public void setUserInfo(UserInfo userInfo) {
		Editor editor = getEditor();
		editor.putString(Constants.KEY_EMAIL, userInfo.getEmail())
				.putString(Constants.KEY_FAMILY_NAME, userInfo.getFamilyName())
				.putString(Constants.KEY_GIVEN_NAME, userInfo.getGivenName())
				.putString(Constants.KEY_GENDER, userInfo.getGender())
				.putString(Constants.KEY_ID, userInfo.getId())
				.putString(Constants.KEY_LINK, userInfo.getLink())
				.putString(Constants.KEY_LOCALE, userInfo.getLocale())
				.putString(Constants.KEY_NAME, userInfo.getName())
				.putString(Constants.KEY_PICTURE, userInfo.getPicture())
				.putBoolean(Constants.KEY_VERIFIED_EMAIL,
						userInfo.isVerifiedEmail());
		editor.commit();
	}

	/**
	 * 認証されたOAuthConsumerの情報から、TOKENとTOKENSECRETを取得し、<br>
	 * SharedPreferencesに保存します。<br>
	 * この情報は、再度ブラウザを表示して認証することなく、<br>
	 * 認証済みの情報を使うことで何度でもユーザの最新情報が取得できます。
	 *
	 * @param consumer
	 */
	public void setOAuthInfo(OAuthConsumer consumer) {
		Editor edit = getEditor();
		edit.putString(OAuth.OAUTH_TOKEN, consumer.getToken());
		edit.putString(OAuth.OAUTH_TOKEN_SECRET, consumer.getTokenSecret());
		edit.commit();
	}

	/**
	 * SharedPreferencesに保存されたユーザ情報を全て削除します。<br>
	 * 認証済みのTOKEN情報も削除されるため、再度認証するひつようがあります。<br>
	 * ※Googleアカウントの認証情報からは削除されません。
	 */
	public void clearAuthAndUserInfo() {
		Editor edit = getEditor();
		edit.remove(OAuth.OAUTH_TOKEN);
		edit.remove(OAuth.OAUTH_TOKEN_SECRET);
		edit.remove(Constants.KEY_EMAIL);
		edit.remove(Constants.KEY_FAMILY_NAME);
		edit.remove(Constants.KEY_GIVEN_NAME);
		edit.remove(Constants.KEY_GENDER);
		edit.remove(Constants.KEY_ID);
		edit.remove(Constants.KEY_LINK);
		edit.remove(Constants.KEY_LOCALE);
		edit.remove(Constants.KEY_NAME);
		edit.remove(Constants.KEY_PICTURE);
		edit.remove(Constants.KEY_VERIFIED_EMAIL);
		edit.commit();
	}

	/**
	 * OAuthConsumerを取得します。<br>
	 * 認証済みの場合、認証情報を保持した状態のOAuthConsumerを返します。
	 *
	 * @return OAuthConsumer
	 */
	public OAuthConsumer getOAuthConsumer() {
		SharedPreferences sp = getSharedPreferences();
		OAuthConsumer consumer = new CommonsHttpOAuthConsumer(
				Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
		consumer.setTokenWithSecret(sp.getString(OAuth.OAUTH_TOKEN, ""),
				sp.getString(OAuth.OAUTH_TOKEN_SECRET, ""));

		return consumer;
	}

	/**
	 * SharedPreferencesへの更新処理を行うためのEditorオブジェクトを取得します。
	 *
	 * @return Editor
	 */
	private Editor getEditor() {
		return getSharedPreferences().edit();
	}

	/**
	 * SharedPreferencesへの参照を返します。<br>
	 * 別に誰か悪さするわけじゃないので読み書きできるオブジェクトで返しちゃいます。
	 *
	 * @return SharedPreferences
	 */
	private SharedPreferences getSharedPreferences() {
		return _context.getSharedPreferences(Constants.SHARED_PREFERENCES_NAME,
				Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
	}
}
